home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / appletalk / uab.shar / ddpport.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-07-12  |  6.3 KB  |  228 lines

  1. static char rcsid[] = "$Author: cck $ $Date: 88/09/14 10:19:03 $";
  2. static char rcsident[] = "$Header: /src/local/mac/cap/etalk/RCS/ddpport.c,v 1.8 88/09/14 10:19:03 cck Rel $";
  3. static char revision[] = "$Revision: 1.8 $";
  4.  
  5. /*
  6.  * ddpport.c - ddp port manager
  7.  *
  8.  * Handles the ddp port which sits on the interface boundary between
  9.  * DDP and LAP.  In addition, it carries the "local delivery" or
  10.  * demuxing information necessary to pass data to individual modules
  11.  *
  12.  *
  13.  * Copyright (c) 1988 by The Trustees of Columbia University 
  14.  *  in the City of New York.
  15.  *
  16.  * Permission is granted to any individual or institution to use,
  17.  * copy, or redistribute this software so long as it is not sold for
  18.  * profit, provided that this notice and the original copyright
  19.  * notices are retained.  Columbia University nor the author make no
  20.  * representations about the suitability of this software for any
  21.  * purpose.  It is provided "as is" without express or implied
  22.  * warranty.
  23.  *
  24.  *
  25.  * Edit History:
  26.  *
  27.  *  Sept 4, 1988  CCKim Created
  28.  *
  29. */
  30.  
  31. static char columbia_copyright[] = "Copyright (c) 1988 by The Trustees of \
  32. Columbia University in the City of New York";
  33.  
  34. #include <stdio.h>
  35. #include <ctype.h>
  36. #include <signal.h>
  37. #include <sys/param.h>
  38. #ifndef _TYPES
  39. # include <sys/types.h>
  40. #endif
  41. #include <sys/socket.h>
  42. #include <sys/ioctl.h>
  43. #include <sys/uio.h>
  44. #include <sys/time.h>
  45. #include <net/if.h>
  46. #include <netinet/in.h>
  47.  
  48. #include <netat/appletalk.h>
  49. #include <netat/compat.h>
  50. #include "ddpport.h"
  51. #include "log.h"
  52.  
  53. private PORT *port_list = NULL;
  54.  
  55. #define LOG_HIGH 1
  56. #define LOG_STD 2
  57.  
  58. /*
  59.  * Establish an open port.
  60.  *  ddp_net, ddp_node - ddp network/node to associate with this port
  61.  *   (0 if not seeded) 
  62.  *  zone - zone if any (null if not)
  63.  *  node - node id of this port (required)
  64.  *  local_handle - local data handle for caller
  65.  *  sendrtn - send data routine
  66.  *  map_fromddp - map ddp net, node to lap node
  67.  *  map_laptoddp - map inverse (not used)
  68.  *  demuxer - demux structure that describes the local delivery mechanism
  69.  *
  70. */
  71. export PORT_T
  72. port_create(ddp_net, ddp_node, zone, node, flags, local_handle,
  73.         sendrtn, map_fromddp, map_laptoddp, demuxer)
  74. word ddp_net;
  75. word ddp_node;
  76. byte *zone;
  77. NODE *node;
  78. int flags;
  79. caddr_t local_handle;
  80. int (*sendrtn)();
  81. NODE *(*map_fromddp)();
  82. int (*map_laptoddp)();
  83. struct mpxddp_module *demuxer;
  84. {
  85.   struct route_entry *re;
  86.   PORT *port;
  87.  
  88.   if ((port = (PORT *)malloc(sizeof(PORT))) == NULL) {
  89.     log(LOG_HIGH|L_UERR, "malloc for port failed");
  90.     return(NULL);
  91.   }
  92.   port->p_next = NULL;
  93.   port->p_flags = flags|PORT_ISCONNECTED; /* mark here */
  94.   port->p_ddp_node = ddp_node;    /* mark ddp node */
  95.   port->p_ddp_net = 0;        /* mark as unknown for now */
  96.   port->p_zonep = NULL;        /* mark as unknown for now */
  97.   port->p_id = node;
  98.   port->p_local_data = local_handle;
  99.   port->p_send_if = sendrtn;
  100.   port->p_map_lap_if = map_fromddp;
  101.   port->p_map_ddp_if = map_laptoddp;
  102.   port->p_mpx = NULL;
  103.   if (ddp_net) {
  104.     port_net_ready(port, ddp_net, NULL); /* this will set ddp_net properly */
  105.     if (route_add_host_entry(port, ddp_net, zone) < 0) {
  106.       log(LOG_HIGH,"***couldn't add host route for port %d, net %d.%d",
  107.       port, nkipnetnumber(ddp_net), nkipnetnumber(ddp_net));
  108.     }
  109.     if (zone)            /* if zone, mark that too */
  110.       port_zone_known(port, zone);
  111.   }
  112.   /* wait until after we set zone, etc if we did */
  113.   if (demuxer) {
  114.     if (!port_setdemuxer(port, demuxer))
  115.       log(LOG_HIGH, "couldn't initialize local divery via %s on port %d\n",
  116.       demuxer->mpx_name,port);
  117.   }
  118.   /* may need to call a lower level grab routine (e.g. if working with */
  119.   /* kernel ddp) */
  120.   return(port);
  121. }
  122.  
  123. /*
  124.  * set and initialize local delivery: can be called later if not set
  125.  * in port create.
  126.  * returns true,false
  127.  *
  128. */
  129. export
  130. port_setdemuxer(port, mpx)
  131. PORT_T port;
  132. struct mpxddp_module *mpx;
  133. {
  134.   int i;
  135.  
  136.   if (mpx == NULL)
  137.     return(TRUE);
  138.   
  139.   if (!mpx->mpx_init || (i = mpx->mpx_init()) < 0) /* init multiplexor */
  140.     return(FALSE);
  141.   if (mpx->mpx_grab)        /* if socket grabber */
  142.     ddp_reopen(mpx->mpx_grab, i, NULL);    /* then call it */
  143.   port->p_mpx_hdl = i;        /* remember handle */
  144.   /* port is ready already! */
  145.   if (mpx->mpx_havenode)    /* always mark node (must be known) */
  146.     (*mpx->mpx_havenode)(i, port->p_ddp_node);
  147.   /* if netready, send down net */
  148.   if ((port->p_flags & PORT_NETREADY) && mpx->mpx_havenet)
  149.       (*mpx->mpx_havenet)(i, port->p_ddp_net, port->p_ddp_node);
  150.   /* if portready then send down zone (==> netready) */
  151.   if ((port->p_flags & PORT_ISREADY) && mpx->mpx_havezone)    
  152.     (*mpx->mpx_havezone)(i, port->p_zonep);
  153.   port->p_mpx = mpx;
  154.   return(TRUE);
  155. }
  156.  
  157. /*
  158.  * get the head of the "lap" interface port list
  159.  *
  160. */
  161. export PORT_T
  162. port_list_start()
  163. {
  164.   return(port_list);
  165. }
  166.  
  167. /*
  168.  * port's net is ready, set vars: return TRUE if was ready
  169.  *
  170.  * (Is this really sufficient?)
  171.  *
  172. */
  173. export boolean
  174. port_net_ready(port, net, sid, zone)
  175. PORT_T port;            /* port */
  176. word net;            /* ddp network for port */
  177. NODE *sid;            /* node the information came from */
  178. byte *zone;            /* zone */
  179. {
  180.   if (port == NULL) {        /* how did this happen? */
  181.     log(LOG_HIGH, "port null in port_net_ready");
  182.     return(FALSE);
  183.   }
  184.   if (port->p_ddp_net == 0) {
  185.     port->p_ddp_net = net;
  186.     port->p_next = port_list;    /* link into list */
  187.     port_list = port;
  188.     port->p_flags |= PORT_NETREADY; /* mark sure marked ready */
  189.     /* set net & bridge info (bridge is ourselves) */
  190.     if (port->p_mpx && port->p_mpx->mpx_havenet)
  191.       (*port->p_mpx->mpx_havenet)(port->p_mpx_hdl, net, port->p_ddp_node);
  192.     return(FALSE);
  193.   }
  194.   if (port->p_ddp_net != net) {
  195.     log(LOG_STD, "***net mismatch: port %d's net is %d.%d, received %d.%d",
  196.     port, nkipnetnumber(port->p_ddp_net),
  197.     nkipsubnetnumber(port->p_ddp_net),
  198.     nkipnetnumber(net), nkipsubnetnumber(net));
  199.     if (sid)
  200.       log(LOG_STD, "offending node: %s",
  201.       node_format(sid));
  202.   } 
  203.   return(TRUE);
  204. }
  205.  
  206. /*
  207.  * zone acquired, returns TRUE, FALSE
  208.  *
  209. */
  210. export boolean
  211. port_zone_known(port,zone)
  212. PORT_T port;
  213. byte *zone;
  214. {
  215.   if (port == NULL) {        /* how did this happen? */
  216.     log(LOG_HIGH, "port null in port_zone_ready");
  217.     return(FALSE);
  218.   }
  219.   if ((port->p_flags & PORT_NETREADY) == 0)
  220.     return(FALSE);
  221.   port->p_flags |= PORT_ISREADY; /* mark sure marked ready */
  222.   /* zone storage is kept */
  223.   port->p_zonep = zone;        /* remember it */
  224.   if (port->p_mpx && port->p_mpx->mpx_havezone)
  225.     (*port->p_mpx->mpx_havezone)(port->p_mpx_hdl, zone);
  226.   return(TRUE);
  227. }
  228.